/*
 *
 *
 */

#ifndef IBASEDATALINK_H_
#define IBASEDATALINK_H_

#define MAX_ERRCNT 3

#include <iostream>

namespace zl
{
namespace zlbase
{

/// \brief 数据链路配置项
struct DatalinkOption
{
	int32_t type;
    bool is_shared; ///< 是否为共享链路

    std::string localaddr;  ///< 本地地址
    int32_t localport;      ///< 本地端口
    std::string remoteaddr; ///< 远程地址
    int32_t remoteport;     ///< 远程端口

    std::string com;        ///< 设备串口名
    int32_t baud_rate;      ///< 串口波特率（默认 9600）
    int32_t flow_control;   ///< 串口流控 （默认 无）
    int32_t parity;         ///< 串口校验位 （默认 无）
    int32_t stop_bits;      ///< 串口停止位 （默认 0）
    int32_t character_size; ///< 串口数据位 （默认 8）

    int32_t timeout_conn;  ///< 连接超时时间(ms)
    int32_t timeout_read;  ///< 读超时时间(ms)
    int32_t timeout_write; ///< 写超时时间(ms)

	DatalinkOption() :
		is_shared(false),
		localaddr(""),
		baud_rate(9600),
		flow_control(0),
		parity(0),
		stop_bits(0),
		character_size(8) {}
};

/// \brief 数据链路层接口类
class IBaseDatalink
{
public:
    /// \brief 链路类型
    enum class EType
    {
        EthernetUDP = 0x01, ///< 以太网口UDP
        EthernetTCP,        ///< 以太网口TCP
        SerialPort          ///< 标准串口
    };

    /// \brief 虚析构函数
    virtual ~IBaseDatalink() = default;

    /// \brief 设置链路选项
    virtual inline void SetOption(const DatalinkOption &option)
    {
        option_ = option;
    }
    virtual inline DatalinkOption Option() { return option_; }

    /// \brief Get datalink origin
    virtual std::string Origin() = 0;

    /// \brief 锁定链路对象
    ///
    /// 获取一个该链路的所有权防止出现多个线程同时读写某一个链路的情况
    /// \param[in] flag true: 获取，false: 释放
    /// \return 获取所有权是否成功
    virtual void AcquireOwnership(bool flag) = 0;

    /// \brief 链路是否打开
    virtual bool IsOpen() { return false; }

    /// \brief 打开链路
    virtual int32_t Open() = 0;

    /// \brief 关闭链路
    virtual int32_t Close() = 0;

    /// \brief 试图从链路中读取数据
    ///
    /// \param[in] buf 用来缓存数据的缓冲区
    /// \param[in] len 缓冲区的长度
    /// \return 实际读取的数据长度
    virtual int32_t Read(unsigned char *buff, size_t len) = 0;

    /// \brief 试图写入部分数据到链路中
    ///
    /// \param[in] buf 写入数据的指针
    /// \param[in] len 要写入数据的长度
    /// \return 实际写入的数据长度
    virtual int32_t Write(const unsigned char *buff, size_t len) = 0;

protected:
    DatalinkOption option_;
};

} // namespace zlbase
} // namespace zl

#endif // IBASEDATALINK_H_
